home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / etc / RCS / getwd.c,v < prev    next >
Text File  |  1992-03-27  |  10KB  |  451 lines

  1. head     1.9;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.9
  10. date     92.03.27.13.36.57;  author rab;  state Exp;
  11. branches ;
  12. next     1.8;
  13.  
  14. 1.8
  15. date     90.08.06.23.38.22;  author jhh;  state Exp;
  16. branches ;
  17. next     1.7;
  18.  
  19. 1.7
  20. date     89.07.31.17.40.32;  author jhh;  state Exp;
  21. branches ;
  22. next     1.6;
  23.  
  24. 1.6
  25. date     89.05.18.17.11.54;  author rab;  state Exp;
  26. branches ;
  27. next     1.5;
  28.  
  29. 1.5
  30. date     89.02.27.16.36.57;  author mgbaker;  state Exp;
  31. branches ;
  32. next     1.4;
  33.  
  34. 1.4
  35. date     89.02.26.16.20.13;  author mgbaker;  state Exp;
  36. branches ;
  37. next     1.3;
  38.  
  39. 1.3
  40. date     88.07.28.17.47.38;  author ouster;  state Exp;
  41. branches ;
  42. next     1.2;
  43.  
  44. 1.2
  45. date     88.07.25.10.45.53;  author ouster;  state Exp;
  46. branches ;
  47. next     1.1;
  48.  
  49. 1.1
  50. date     88.06.27.15.35.44;  author ouster;  state Exp;
  51. branches ;
  52. next     ;
  53.  
  54.  
  55. desc
  56. @@
  57.  
  58.  
  59. 1.9
  60. log
  61. @Fixed some lint errors.
  62. @
  63. text
  64. @/*
  65.  * Copyright (c) 1980 Regents of the University of California.
  66.  * All rights reserved.  The Berkeley software License Agreement
  67.  * specifies the terms and conditions for redistribution.
  68.  */
  69.  
  70. #if defined(LIBC_SCCS) && !defined(lint)
  71. static char sccsid[] = "@@(#)getwd.c    5.2 (Berkeley) 3/9/86";
  72. #endif LIBC_SCCS and not lint
  73.  
  74. /*
  75.  * getwd() returns the pathname of the current working directory. On error
  76.  * an error message is copied to pathname and null pointer is returned.
  77.  */
  78.  
  79. #include <stdio.h>
  80. #include <sys/param.h>
  81. #include <sys/stat.h>
  82. #include <sys/dir.h>
  83. #include <sys/file.h>
  84.  
  85. #include <sprite.h>
  86. #include <fs.h>
  87. #include <sysStats.h>
  88.  
  89. #define GETWDERR(s)    (void) strcpy(pathname, (s));
  90.  
  91. static char *prepend();
  92.  
  93. extern char *strcpy();
  94. static int pathsize;            /* pathname length */
  95.  
  96. static char *oldGetwd();
  97.  
  98. char *
  99. getwd(pathname)
  100.     char *pathname;
  101. {
  102.     char pathbuf[MAXPATHLEN];        /* temporary pathname buffer */
  103.     char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */
  104.     char curdir[MAXPATHLEN];        /* current directory buffer */
  105.     char *dptr = curdir;        /* directory pointer */
  106.     char *prepend();            /* prepend dirname to pathname */
  107.     int cdev;                /* current & root device number */
  108.     int cino;                /* current & root inode number */
  109.     int curServer;            /* current and root server ID */
  110.     DIR *dirp;                /* directory stream */
  111.     struct direct *dir;            /* directory entry struct */
  112.     Fs_Attributes d;            /* file status struct */
  113.     int fd;                /* Handle on current directory */
  114.     Ioc_PrefixArgs iocPrefix;        /* Returned by ioctl. */
  115.     ReturnStatus status;
  116.  
  117.     pathsize = 0;
  118.     *pnptr = '\0';
  119.     fd = open(".", O_RDONLY);
  120.     if (fd < 0) {
  121.     GETWDERR("getwd: can't open .");
  122.     }
  123.     status = Fs_IOControl(fd, IOC_PREFIX, 0, NULL, sizeof(Ioc_PrefixArgs), 
  124.         &iocPrefix);
  125.  
  126.     if (status != SUCCESS) {
  127.     /*
  128.      * If the ioctl fails assume we are on an old kernel and do it the
  129.      * old way.
  130.      */
  131. #if 0
  132.     printf("Using old getwd -- \"%s\".\n", Stat_GetMsg(status));
  133. #endif
  134.     return oldGetwd(pathname);
  135.     }
  136.     close(fd);
  137.     (void) strcpy(dptr, "./");
  138.     dptr += 2;
  139.     if (Fs_GetAttributes(curdir, FS_ATTRIB_FILE, &d) != SUCCESS) {
  140.         GETWDERR("getwd: can't stat .");
  141.         return (NULL);
  142.     }
  143.     for (;;) {
  144.     cino = d.fileNumber;
  145.     cdev = d.domain;
  146.     curServer = d.serverID;
  147.     (void) strcpy(dptr, "../");
  148.     dptr += 3;
  149.     if ((dirp = opendir(curdir)) == NULL) {
  150.         GETWDERR("getwd: can't open ..");
  151.         return (NULL);
  152.     }
  153.     Fs_GetAttributesID(dirp->dd_fd, &d);
  154.     if (curServer == d.serverID && cdev == d.domain) {
  155.         /*
  156.          * Parent directory is in the same domain as the current point.
  157.          * Check against root loop and then scan parent looking for match.
  158.          */
  159.         if (cino == d.fileNumber) {
  160.         /* reached root directory */
  161.         closedir(dirp);
  162.         break;
  163.         }
  164.         do {
  165.         if ((dir = readdir(dirp)) == NULL) {
  166.             closedir(dirp);
  167.             GETWDERR("getwd: read error in ..");
  168.             return (NULL);
  169.         }
  170.         } while (dir->d_ino != cino);
  171.         closedir(dirp);
  172.         pnptr = prepend("/", prepend(dir->d_name, pnptr));
  173.     } else {
  174.         /*
  175.          * The parent directory is in a different domain.  This means that
  176.          * the current point should be the root of a domain and this
  177.          * host should have a prefix that corresponds to it. 
  178.          * We already have the prefix from the ioctl, so just break.
  179.          */
  180.         closedir(dirp);
  181.         break;
  182.     }
  183.     }
  184.     if ((strcmp(iocPrefix.prefix, "/") != 0) || (*pnptr == 0)) {
  185.     pnptr = prepend(iocPrefix.prefix, pnptr);
  186.     }
  187.     (void) strcpy(pathname, pnptr);
  188.     return (pathname);
  189. }
  190.  
  191. /*
  192.  * prepend() tacks a directory name onto the front of a pathname.
  193.  */
  194. static char *
  195. prepend(dirname, pathname)
  196.     register char *dirname;
  197.     register char *pathname;
  198. {
  199.     register int i;            /* directory name size counter */
  200.  
  201.     for (i = 0; *dirname != '\0'; i++, dirname++)
  202.         continue;
  203.     if ((pathsize += i) < MAXPATHLEN)
  204.         while (i-- > 0)
  205.             *--pathname = *--dirname;
  206.     return (pathname);
  207. }
  208.  
  209. static char *
  210. oldGetwd(pathname)
  211.     char *pathname;
  212. {
  213.     char pathbuf[MAXPATHLEN];        /* temporary pathname buffer */
  214.     char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */
  215.     char curdir[MAXPATHLEN];        /* current directory buffer */
  216.     char *dptr = curdir;        /* directory pointer */
  217.     char *prepend();            /* prepend dirname to pathname */
  218.     int cdev, rdev;            /* current & root device number */
  219.     int cino, rino;            /* current & root inode number */
  220.     int curServer, rootServer;        /* current and root server ID */
  221.     DIR *dirp;                /* directory stream */
  222.     struct direct *dir;            /* directory entry struct */
  223.     Fs_Attributes d;            /* file status struct */
  224.  
  225.     pathsize = 0;
  226.     *pnptr = '\0';
  227.     if (Fs_GetAttributes("/", FS_ATTRIB_FILE, &d) != SUCCESS) {
  228.         GETWDERR("getwd: can't stat /");
  229.         return (NULL);
  230.     }
  231.     rdev = d.domain;
  232.     rino = d.fileNumber;
  233.     rootServer = d.serverID;
  234.     (void) strcpy(dptr, "./");
  235.     dptr += 2;
  236.     if (Fs_GetAttributes(curdir, FS_ATTRIB_FILE, &d) != SUCCESS) {
  237.         GETWDERR("getwd: can't stat .");
  238.         return (NULL);
  239.     }
  240.     for (;;) {
  241.     if (d.fileNumber == rino && d.domain == rdev
  242.         && d.serverID == rootServer)
  243.         break;        /* reached root directory */
  244.     cino = d.fileNumber;
  245.     cdev = d.domain;
  246.     curServer = d.serverID;
  247.     (void) strcpy(dptr, "../");
  248.     dptr += 3;
  249.     if ((dirp = opendir(curdir)) == NULL) {
  250.         GETWDERR("getwd: can't open ..");
  251.         return (NULL);
  252.     }
  253.     Fs_GetAttributesID(dirp->dd_fd, &d);
  254.     if (curServer == d.serverID && cdev == d.domain) {
  255.         /*
  256.          * Parent directory is in the same domain as the current point.
  257.          * Check against root loop and then scan parent looking for match.
  258.          */
  259.         if (cino == d.fileNumber) {
  260.         /* reached root directory */
  261.         closedir(dirp);
  262.         break;
  263.         }
  264.         do {
  265.         if ((dir = readdir(dirp)) == NULL) {
  266.             closedir(dirp);
  267.             GETWDERR("getwd: read error in ..");
  268.             return (NULL);
  269.         }
  270.         } while (dir->d_ino != cino);
  271.         closedir(dirp);
  272.         pnptr = prepend("/", prepend(dir->d_name, pnptr));
  273.     } else {
  274.         /*
  275.          * The parent directory is in a different domain.  This means that
  276.          * the current point should be the root of a domain and this
  277.          * host should have a prefix that corresponds to it.  Scan the
  278.          * prefix table looking for a match.
  279.          */
  280.         register int index;
  281.         Fs_Prefix prefix;
  282.         closedir(dirp);
  283.         for (index=0 ; ; index++) {
  284.         bzero((char *) &prefix, sizeof(Fs_Prefix));
  285.         if (Sys_Stats(SYS_FS_PREFIX_STATS, index, (Address) &prefix)
  286.             != SUCCESS) {
  287.             sprintf(pathname,
  288.             "getwd: missing prefix %s", pnptr);
  289.             return(NULL);
  290.         }
  291.         if (prefix.serverID == curServer &&
  292.             prefix.domain == cdev &&
  293.             prefix.fileNumber == cino) {
  294.             pnptr = prepend(prefix.prefix, pnptr);
  295.             goto done;
  296.         }
  297.         }
  298.     }
  299.     }
  300. done:
  301.     if (*pnptr == '\0')    {    /* current dir == root dir */
  302.         (void) strcpy(pathname, "/");
  303.     } else {
  304.     strcpy(pathname, pnptr);
  305.     }
  306.     return (pathname);
  307. }
  308. @
  309.  
  310.  
  311. 1.8
  312. log
  313. @didn't close directory properly.
  314. @
  315. text
  316. @d26 1
  317. a26 1
  318. #define GETWDERR(s)    strcpy(pathname, (s));
  319. d30 1
  320. a30 1
  321. char *strcpy();
  322. d74 1
  323. a74 1
  324.     strcpy(dptr, "./");
  325. d84 1
  326. a84 1
  327.     strcpy(dptr, "../");
  328. d124 1
  329. a124 1
  330.     strcpy(pathname, pnptr);
  331. d171 1
  332. a171 1
  333.     strcpy(dptr, "./");
  334. d184 1
  335. a184 1
  336.     strcpy(dptr, "../");
  337. d238 5
  338. a242 4
  339.     if (*pnptr == '\0')        /* current dir == root dir */
  340.         strcpy(pathname, "/");
  341.     else
  342.         strcpy(pathname, pnptr);
  343. @
  344.  
  345.  
  346. 1.7
  347. log
  348. @now understands synonymous prefixes and will chose correct one.
  349. @
  350. text
  351. @d117 1
  352. @
  353.  
  354.  
  355. 1.6
  356. log
  357. @Added forward declarations for static functions.
  358. @
  359. text
  360. @d20 1
  361. d33 2
  362. d44 110
  363. a241 18
  364. }
  365.  
  366. /*
  367.  * prepend() tacks a directory name onto the front of a pathname.
  368.  */
  369. static char *
  370. prepend(dirname, pathname)
  371.     register char *dirname;
  372.     register char *pathname;
  373. {
  374.     register int i;            /* directory name size counter */
  375.  
  376.     for (i = 0; *dirname != '\0'; i++, dirname++)
  377.         continue;
  378.     if ((pathsize += i) < MAXPATHLEN)
  379.         while (i-- > 0)
  380.             *--pathname = *--dirname;
  381.     return (pathname);
  382. @
  383.  
  384.  
  385. 1.5
  386. log
  387. @Removed sun4 cpp hack.  I put it in fs.h instead.
  388. @
  389. text
  390. @d26 2
  391. @
  392.  
  393.  
  394. 1.4
  395. log
  396. @Added fix due to sun4 cpp problem with expanding macros inside structure
  397. definitions.
  398. @
  399. text
  400. @a21 12
  401.  
  402. /*
  403.  * The macros major and minor are defined in sys/types.h.  They are also
  404.  * the names of fields in a structure defined in fs.h.  Unfortunately, cpp
  405.  * on the sun4 expands the macros inside the structure field names, so I
  406.  * undefine and redefine them here around the inclusion of fs.h.
  407.  */
  408. #ifdef sun4
  409. #undef major
  410. #undef minor
  411. #endif sun4
  412.  
  413. a22 6
  414.  
  415. #ifdef sun4
  416. #define major(x)        ((int)(((unsigned)(x)>>8)&0377))
  417. #define minor(x)        ((int)((x)&0377))
  418. #endif sun4
  419.  
  420. @
  421.  
  422.  
  423. 1.3
  424. log
  425. @Lint.
  426. @
  427. text
  428. @d22 12
  429. d35 6
  430. @
  431.  
  432.  
  433. 1.2
  434. log
  435. @Lint.
  436. @
  437. text
  438. @d115 1
  439. a115 1
  440.             pnptr = prepend(prefix.prefix, pnptr, &pathsize);
  441. @
  442.  
  443.  
  444. 1.1
  445. log
  446. @Initial revision
  447. @
  448. text
  449. @d16 1
  450. @
  451.